package cn.mijack.face.service;

import android.graphics.Bitmap;
import android.graphics.Matrix;

import com.facepp.error.FaceppParseException;
import com.facepp.http.HttpRequests;
import com.facepp.http.PostParameters;

import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import rx.Observable;
import rx.Subscriber;

/**
 * Created by MiJack on 2016/6/7.
 */
public class FaceService {
    public static Observable<JSONObject> uploadImage(final Bitmap img) {
        return Observable.create(new Observable.OnSubscribe<JSONObject>() {
            @Override
            public void call(Subscriber<? super JSONObject> subscriber) {
                HttpRequests httpRequests = new HttpRequests(
                        ApiKey.API_KEY,
                        ApiKey.API_SECRET, true, false);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                float scale = Math.min(1, Math.min(600f / img.getWidth(), 600f / img.getHeight()));
                Matrix matrix = new Matrix();
                matrix.postScale(scale, scale);

                Bitmap imgSmall = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, false);

                imgSmall.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                byte[] array = stream.toByteArray();
                try {
                    JSONObject result = httpRequests.detectionDetect(new PostParameters().setImg(array).setMode("oneface"));
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                } catch (FaceppParseException e) {
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });
    }

    public static Observable<JSONObject> createFaceSet(final String faceSetName) {
        return Observable.create(new Observable.OnSubscribe<JSONObject>() {
            @Override
            public void call(Subscriber<? super JSONObject> subscriber) {
                HttpRequests httpRequests = new HttpRequests(
                        ApiKey.API_KEY,
                        ApiKey.API_SECRET, true, false);
                try {
                    JSONObject result = httpRequests.facesetCreate(new PostParameters().setFacesetName(faceSetName));
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                } catch (FaceppParseException e) {
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });
    }

    public static Observable<JSONObject> add2FaceSet(final String faceId, final String faceSetId) {
        return Observable.create(new Observable.OnSubscribe<JSONObject>() {
            @Override
            public void call(Subscriber<? super JSONObject> subscriber) {
                HttpRequests httpRequests = new HttpRequests(
                        ApiKey.API_KEY,
                        ApiKey.API_SECRET, true, false);
                try {
                    PostParameters parameters = new PostParameters().setFaceId(faceId).setFacesetId(faceSetId);
                    JSONObject result = httpRequests.facesetAddFace(parameters);
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                } catch (FaceppParseException e) {
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });
    }

    public static Observable<JSONObject> obtainFaceSet(final String faceSetName) {
        return Observable.create(new Observable.OnSubscribe<JSONObject>() {
            @Override
            public void call(Subscriber<? super JSONObject> subscriber) {
                HttpRequests httpRequests = new HttpRequests(
                        ApiKey.API_KEY,
                        ApiKey.API_SECRET, true, false);
                try {
                    JSONObject result = httpRequests.facesetGetInfo(
                            new PostParameters().setFacesetName(faceSetName));
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                } catch (FaceppParseException e) {
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });
    }

    public static Observable<JSONObject> recognitionSearch(final String faceId, final String faceSetId) {
        return Observable.create(new Observable.OnSubscribe<JSONObject>() {
            @Override
            public void call(Subscriber<? super JSONObject> subscriber) {
                HttpRequests httpRequests = new HttpRequests(
                        ApiKey.API_KEY,
                        ApiKey.API_SECRET, true, false);
                try {
                    JSONObject result = httpRequests.recognitionSearch(
                            new PostParameters().setFacesetId(faceSetId).setKeyFaceId(faceId));
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                } catch (FaceppParseException e) {
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });
    }

    public static Observable<JSONObject> recognitionSearchByFaceSetName(final String faceId, final String faceSetId) {
        return Observable.create(new Observable.OnSubscribe<JSONObject>() {
            @Override
            public void call(Subscriber<? super JSONObject> subscriber) {
                HttpRequests httpRequests = new HttpRequests(
                        ApiKey.API_KEY,
                        ApiKey.API_SECRET, true, false);
                try {
                    JSONObject result = httpRequests.recognitionSearch(
                            new PostParameters().setFacesetName(faceSetId).setKeyFaceId(faceId));
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                } catch (FaceppParseException e) {
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });
    }

    public static Observable<JSONObject> getFace(final String faceId) {
        return Observable.create(new Observable.OnSubscribe<JSONObject>() {
            @Override
            public void call(Subscriber<? super JSONObject> subscriber) {
                HttpRequests httpRequests = new HttpRequests(
                        ApiKey.API_KEY,
                        ApiKey.API_SECRET, true, false);
                try {
                    JSONObject result = httpRequests.infoGetFace(
                            new PostParameters().setFaceId(faceId));
                    subscriber.onNext(result);
                    subscriber.onCompleted();
                } catch (FaceppParseException e) {
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });    }
}
